
package isv

import (
    "dhfshop/models"
	"strings"
	"errors"
	"time"
	"dhfshop/models/consts"
	"github.com/astaxie/beego/orm"
)

// 素材上传记录表
type MaterialRecord struct {
	MaterialRecId int64  `orm:"column(materail_rec_id);pk;auto" json:"materail_rec_id"` 
    PartnerId     int64  `orm:"column(partner_id);index" json:"partner_id"`     //商家ID
	AppId         string `orm:"column(app_id);size(32)" json:"app_id"`          //公众号appid
	PropertyId    int16  `orm:"column(property_id)" json:"property_id"`         //属性ID: 1  永久素材， 2 临时素材
	MediaType     string `orm:"column(media_type)" json:"media_type"`           //媒体类型
	MediaId       string `orm:"column(media_id)" json:"media_id"`               //媒体标识
	CreatedAt     int64  `orm:"column(created_at)" json:"created_at"`           //创建时间
	ExpiredAt     int64  `orm:"column(expired_at)" json:"expired_at"`           //临时素材的过期时间
}

// 永久素材模拟表
type MateSimuTask struct {
	MateSimuTaskId int64  `orm:"column(mate_simu_task_id);pk" json:"mate_simu_task_id,string" form:"-"` //唯一算法生成
	PartnerId      int64  `orm:"column(partner_id);index" json:"partner_id" form:"partner_id"`      //商家ID
	AppId          string `orm:"column(app_id);size(32)" json:"app_id" form:"app_id"`               //公众号appid
	ApplyType      string `orm:"column(apply_type);size(128)" json:"apply_type" form:"apply_type"`   //应用类型
	MediaType      string `orm:"column(media_type);size(16)" json:"media_type" form:"media_type"`   //媒体类型
	MediaId        string `orm:"column(media_id);size(128)" json:"media_id" form:"media_id"`        //微信媒体标识
	LocalUrl       string `orm:"column(local_url);size(1024)" json:"local_url" form:"local_url"`    //本地图片存储URL
	Referenced     string `orm:"column(referenced);size(1024)" json:"referenced" form:"referenced"` //引用对象,有引用标志就需要维护，不能删除
	CreatedAt time.Time   `orm:"auto_now_add;column(created_at);type(datetime)" json:"-" form:"-"`  //创建时间
	ExpiredAt time.Time   `orm:"column(expired_at);type(datetime)" json:"-" form:"-"`               //临时素材的过期时间
	//
	CreatedAtStr   string `orm:"-" json:"created_at" form:"-"`
	ExpiredAtStr   string `orm:"-" json:"expired_at" form:"-"`
	 TaskIdStr     string `orm:"-" json:"-" form:"mate_simu_task_id"`                               //
}

func init() {
    orm.RegisterModel(new(MaterialRecord),new(MateSimuTask))   
}

func AddMaterialRecord(m *MaterialRecord) (id int64, err error) {
	o := models.GetDefaultDB()
	id, err = o.Insert(m)
	return
}

func GetMaterialRecordById(id int64) (v *MaterialRecord, err error) {
	o := models.GetDefaultDB()
	v = &MaterialRecord{MaterialRecId: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}

func GetAllMaterialRecords(query map[string]string, fields []string, order_by map[string]string, 
    offset int, limit int) ([]*MaterialRecord, int64,error) {
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(MaterialRecord))
	if start, ok := query["start_created"]; ok {
		if startTime, err := time.Parse(consts.DATELINKTIME_FORMAT, start); err == nil {
		    qs = qs.Filter("created_at__gte", startTime)
		}
		delete(query, "start_created")
	}
	if end, ok := query["end_created"]; ok {
		if endTime, err := time.Parse(consts.DATELINKTIME_FORMAT, end); err == nil {
	        qs = qs.Filter("created_at__lte", endTime)
	    }
		delete(query, "end_created")
	}
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	cnt, err := qs.Count()
	// order by:
	var sortFields []string
	for k, v := range order_by {
		orderby := ""
		if v == "desc" {
			orderby = "-" + k
		} else if v == "asc" {
			orderby = k
		} else {
			return nil, 0, errors.New("Error: Invalid order. Must be either [asc|desc]")
		}
		sortFields = append(sortFields, orderby)
	}
	qs = qs.OrderBy(sortFields...)
	var lists []*MaterialRecord
	if _, err := qs.Limit(limit, offset).All(&lists, fields...); err == nil {
		return lists, cnt, nil
	}
	return nil, 0, err
}

func UpdateMaterialRecordById(m *MaterialRecord, k ...string) (id int64, err error) {
	o := models.GetDefaultDB()
	v := MaterialRecord{MaterialRecId: m.MaterialRecId}
	if err = o.Read(&v); err == nil {
	    m.MaterialRecId = v.MaterialRecId
		if id, err = o.Update(m, k...); err != nil {
		   return
		}
	}
	return
}

func DeleteMaterialRecordById(id int64) (err error) {
	o := models.GetDefaultDB()
	v := MaterialRecord{MaterialRecId: id}
	if err = o.Read(&v); err == nil {
		if _, err = o.Delete(&v); err == nil {
			return nil
		}
	}
	return
}

/****************************************/
func AddMateSimuTask(m *MateSimuTask) (id int64, err error) {
	o := models.GetDefaultDB()
	id, err = o.Insert(m)
	return
}

func GetMateSimuTaskById(id int64) (v *MateSimuTask, err error) {
	o := models.GetDefaultDB()
	v = &MateSimuTask{MateSimuTaskId: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}

func GetAllMateSimuTasks(query map[string]string, fields []string, order_by map[string]string, 
    offset int, limit int) ([]*MateSimuTask, int64,error) {
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(MateSimuTask))
	if start, ok := query["start_created"]; ok {
		if startTime, err := time.Parse(consts.DATELINKTIME_FORMAT, start); err == nil {
		    qs = qs.Filter("created_at__gte", startTime)
		}
		delete(query, "start_created")
	}
	if end, ok := query["end_created"]; ok {
		if endTime, err := time.Parse(consts.DATELINKTIME_FORMAT, end); err == nil {
	        qs = qs.Filter("created_at__lte", endTime)
	    }
		delete(query, "end_created")
	}
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	cnt, err := qs.Count()
	// order by:
	var sortFields []string
	for k, v := range order_by {
		orderby := ""
		if v == "desc" {
			orderby = "-" + k
		} else if v == "asc" {
			orderby = k
		} else {
			return nil, 0, errors.New("Error: Invalid order. Must be either [asc|desc]")
		}
		sortFields = append(sortFields, orderby)
	}
	qs = qs.OrderBy(sortFields...)
	var lists []*MateSimuTask
	if _, err := qs.Limit(limit, offset).All(&lists, fields...); err == nil {
		return lists, cnt, nil
	}
	return nil, 0, err
}

func UpdateMateSimuTaskById(m *MateSimuTask, k ...string) (id int64, err error) {
	o := models.GetDefaultDB()
	v := MateSimuTask{MateSimuTaskId: m.MateSimuTaskId}
	if err = o.Read(&v); err == nil {
	    m.MateSimuTaskId = v.MateSimuTaskId
		if id, err = o.Update(m, k...); err != nil {
		   return
		}
	}
	return
}

func DeleteMateSimuTaskById(id int64) (err error) {
	o := models.GetDefaultDB()
	v := MateSimuTask{MateSimuTaskId: id}
	if err = o.Read(&v); err == nil {
		if _, err = o.Delete(&v); err == nil {
			return nil
		}
	}
	return
}

//h, _:= time.ParseDuration("1m") 
//h, _:= time.ParseDuration("-1h")   
//sourceAt.Add(24*h)
func GetRecentExpiredTask(limit, offset int)([]*MateSimuTask, error) {
	h, _:= time.ParseDuration("1h")
	curUtcTime := time.Now().UTC()
	delayOneHour := curUtcTime.Add(1*h)
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(MateSimuTask))
	qs = qs.Filter("expired_at__lte", delayOneHour)
	var lists []*MateSimuTask
	_, err := qs.Limit(limit, offset).All(&lists)
	if err == nil {
		return lists, nil
	}
	return nil, err
}

